#pragma once
#include "Log.hpp"
#include "util.hpp"

namespace my_cloud {
    class DataManager {
    private:
        std::string _backup_file;
        std::unordered_map<std::string, std::string> _table;
    public:
        DataManager(const std::string& backup_file): _backup_file(backup_file){
            InitLoad();
        }
        void Insert(const std::string& key, const std::string& val) {
            _table[key] = val;
            Storage();
        }
        void Updata(const std::string& key, const std::string& val) {
            _table[key] = val;
            Storage();
        }
        bool GetOneByKey(const std::string& key, std::string* val) {
            auto it = _table.find(key);
            if (it != _table.end()) {
                *val = it->second;
                return true;
            }
            LOG(WARING, "Can Not Find " + key);
            return false;
        }
        int Split(const std::string& str, const std::string& sep, std::vector<std::string>* arry) {
            int count = 0;
            size_t pos = 0, idx = 0;
            while (1) {
                pos = str.find(sep, idx);
                if (pos == std::string::npos) {
                    break;
                }
                if (pos == idx) {
                    idx = pos + sep.size();
                    continue;
                }
                std::string tmp = str.substr(idx, pos - idx);
                arry->push_back(tmp);
                count++;
                idx = pos + sep.size();
            }
            if (idx < str.size()) {
                arry->push_back(str.substr(idx));
                count++;
            }
            return count;
        }
        void Storage() {
            FileUtil fu(_backup_file);
            auto it = _table.begin();
            std::stringstream ss;
            for (; it != _table.end(); ++it) {
                ss << it->first << " " << it->second << "\n";
            }   
            fu.SetContent(ss.str());
        }
        bool InitLoad() {
            FileUtil fu(_backup_file);
            std::string content;
            fu.GetContent(content);
            std::vector<std::string> arry;
            Split(content, "\n", &arry);
            for (auto& str : arry) {
                std::vector<std::string> tmp;
                Split(str, " ", &tmp);
                if (tmp.size() != 2) {
                    LOG(WARING, "Split Error!");
                    continue;
                }
                _table[tmp[0]] = tmp[1];
            }
            return true;
        }
    };
}
